package com.xyongfeng.foodManagement.shiro;

import cn.hutool.json.JSONUtil;
import com.xyongfeng.foodManagement.common.BaseResponse;
import com.xyongfeng.foodManagement.common.ErrorCode;
import com.xyongfeng.foodManagement.common.ResultUtils;
import com.xyongfeng.foodManagement.constant.MyConstant;
import com.xyongfeng.foodManagement.domain.AdminInfo;
import com.xyongfeng.foodManagement.domain.vo.AdminInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AuthFilter extends AuthenticatingFilter {


    //生成自定义token
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        //从header中获取token
        AdminInfoVO adminObj = (AdminInfoVO)httpServletRequest.getSession().getAttribute(MyConstant.LOGIN_USER);
        UsernamePasswordToken token = new UsernamePasswordToken();
        token.setUsername(adminObj.getAdminUsername());
        token.setPassword(adminObj.getAdminUsername().toCharArray());
        return token;
    }

    //所有请求全部拒绝访问
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //允许option请求通过
        if (((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())) {
            return true;
        }
        return false;
    }

    //拒绝访问的请求，onAccessDenied方法先获取 token，再调用executeLogin方法
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        Object adminObj = httpServletRequest.getSession().getAttribute(MyConstant.LOGIN_USER);

        //StringUtils.isBlank(String str)  判断str字符串是否为空或者长度是否为0
        if (!(adminObj instanceof AdminInfoVO)) {
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
            httpServletResponse.setCharacterEncoding("UTF-8");
            BaseResponse error = ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR.getCode(), "请先登录");
            httpServletResponse.getWriter().write(JSONUtil.toJsonStr(error));
            return false;
        }
        return executeLogin(request, response);
    }

    //token失效时调用
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setContentType("application/json;charset=utf-8");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpResponse.setCharacterEncoding("UTF-8");
        try {
            //处理登录失败的异常
            Throwable throwable = e.getCause() == null ? e : e.getCause();

            BaseResponse error = ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR.getCode(), "登录凭证已失效，请重新登录");

            httpResponse.getWriter().write(JSONUtil.toJsonStr(error));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return false;
    }
}